﻿/*****************************************************************************
 * Copyright (C) 2009 Gwathuirim
 *
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version.
 *
 * This is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Public License for more details
 *
 * To obtain a copy of the GNU General Public License, please see
 * <http://www.gnu.org.licenses/>
 *****************************************************************************/

// ==UserScript==
// @name           Imperion - ReportsAsMail
// @namespace      http://code.google.com/p/imperion-gm/
// @include        http://*.imperion.*/report/index*
// @include        http://*.imperion.*/report/update*
// @require        http://imperion-gm.googlecode.com/svn/trunk/resources/jquery-1.3.2.js
// ==/UserScript==

(function() {

/**********************************************************************************/
/** Language support **************************************************************/
/**********************************************************************************/

/* language entries */
var language = new Object();

/* German */
/* For the *.imperion.de servers */
language['de'] = new Object();
language['de']['sendAsMail'] 		= "Als E-Mail schicken";
language['de']['sendAsOneMail']		= "Es wurde mehr als ein Bericht ausgewählt. Sollen die Berichte als eine E-Mail gesendet werden?";
language['de']['error']				= "Es ist ein unerwarteter Fehler aufgetreten. Eventuell funktioniert der Server nicht richtig";
language['de']['error_404']			= "Dem aktuellen Account konnte keine E-Mail Adresse zugeordnet werden.";
language['de']['ship1_terrans']		= "Sonde";
language['de']['ship1_titans']		= "Observer";
language['de']['ship1_xen']			= "Zek";

/* English */
/* For the *.imperion.org servers */
language['org'] = new Object();
language['org']['sendAsMail'] 		= "send as e-mail";
language['org']['sendAsOneMail']	= "TODO: sendAsOneMail";

/* Determine TLD for language support */
var languageKey = window.location.hostname;
languageKey = languageKey.split(".");
languageKey = languageKey[languageKey.length - 1];

var currentLanguage = language[languageKey];
var $l = function(key) { return currentLanguage[key]; }

/**********************************************************************************/
/** ReportToMail *****************************************************************/
/**********************************************************************************/

ReportToMail = new Object();

ReportToMail.serverPath = "";

/**
 * Initializes the ReportToMail System.
 */ 
ReportToMail.initialize = function() {
	this.renderSendAsMailButton();
}

/**
 * Creates a new button element, styled like a original button.
 */ 
ReportToMail.createNewButton = function(id, caption) {
	var htmlArray = new Array(
		"<a id='" + id + "' class='buttonStd floatRight marginRight15 interface_forms_buttons_standart'  href='#'>",
			"<span class='interface_forms_buttons_standart'></span>",
			"<div class='checkbox interface_forms_checkbox_on'></div>",
			caption,					
		"</a>"
	);
	
	return $(htmlArray.join(""));
}

/**
 * Initializes the ReportToMail System.
 */ 
ReportToMail.renderSendAsMailButton = function() {
	var nextPageButton = $(".navigation.floatLeft");
	
	/* Render the sendAsMailButton */
	var sendAsMailButton = this.createNewButton("sendAsMailButton", $l("sendAsMail"));
	sendAsMailButton.bind("click", {thisObj: this}, function(event) {
		event.data.thisObj.sendAsMailButtonClicked();
	});
	nextPageButton.append(sendAsMailButton);
}

/**
 * Function called onClick by the sendAsMailButton
 */ 
ReportToMail.sendAsMailButtonClicked = function() {
	var collectedMessages = this.collectCheckedReports();
	if (collectedMessages.length > 0)
		this.sendReportsAsMail(collectedMessages);
}

/**
 * Sends the given messages to the php endpoint.
 */ 
ReportToMail.sendReportsAsMail = function(messageSet) {
	var requestObject = new Object();
	requestObject.host = window.location.host;
	requestObject.language = languageKey;
	
	if (messageSet.length > 1)
		requestObject.sendAsOneMail = window.confirm($l("sendAsOneMail"));
	
	//Store some general values
	requestObject.username = $("a[href=/userProfile/index]").text();
	
	//Find out the species
	var speciesStyleSheetLink = $("link[rel=stylesheet]").eq(2).attr("href");
	requestObject.playerSpecies = speciesStyleSheetLink.match("xen");
	if (requestObject.playerSpecies == null)
		requestObject.playerSpecies = speciesStyleSheetLink.match("terrans");
	if (requestObject.playerSpecies == null)
		requestObject.playerSpecies = speciesStyleSheetLink.match("titans");
	requestObject.playerSpecies = requestObject.playerSpecies[0];
	
	//Store the checked messages
	requestObject.reports = new Array();
	messageSet.each(function() {
		var $this = $(this); //This var contains the tr element and corresponding children

		//Show loading status
		var statusElement = $this.find(".status>div")
		statusElement.css({"background-image": "url(" + ReportToMail.serverPath + "resources/img/loader.gif)", "height": "16px", "width": "16px"});
		
		//fetch the message
		var messageUrl = $this.find(".p13>a").attr("href");
		var fetchedMessage = ReportToMail.fetchReportAsObject("http://" + window.location.host + messageUrl);
		
		if (fetchedMessage != null)
			requestObject.reports.push(fetchedMessage); //alert(JSON.stringify(fetchedMessage));
	});
	
	//alert(JSON.stringify(requestObject));
	var thisObj = this;
	GM_xmlhttpRequest({
		method: "POST",
		url: this.serverPath + "index.php",
		data: JSON.stringify(requestObject),
		onload: function(response) {
			//alert(response.responseText);
			
			try {
				var responseObject = JSON.parse(response.responseText);
				thisObj.processResponseObject(messageSet, responseObject);
			} catch (e) {
				alert($l("error"));
				thisObj.processResponseObject(messageSet, null);
			}
		}
	});
}

/**
 * updates the report statuses
 */ 
ReportToMail.processResponseObject = function(messageSet, responseObject) {
	if (responseObject != null && responseObject.error != undefined) {
		alert($l("error_" + responseObject.errorCode));
		
		messageSet.find(".status>div").css({"background-image": "url(" + ReportToMail.serverPath + "resources/img/error.png)", "height": "16px", "width": "16px"});
		return;
	}
	
	messageSet.each(function() {
		$this = $(this);
		
		var hrefArray = $this.find(".p13>a").attr("href").split("/");
		var reportId = hrefArray[hrefArray.length - 1];
		var statusName = "error";
		if (responseObject != null && responseObject[reportId] != undefined && responseObject[reportId].code == 200)
			statusName = "ok";
			
		var statusElement = $this.find(".status>div");
		statusElement.css({"background-image": "url(" + ReportToMail.serverPath + "resources/img/" + statusName + ".png)", "height": "16px", "width": "16px"});
	});
}

/**
 * Fetches a message with the given url.
 */ 
ReportToMail.fetchReportAsObject = function(messageUrl) {
	var fetchedMarkup = $($.ajax({
		type: "GET",
		url: messageUrl,
		async: false
	}).responseText);
	
	//parse the report markup
	var reportId = messageUrl.split("/")[8];
	var reportType = messageUrl.split("/")[6];	
	
	var report = this.parseReportMarkup(reportId, reportType, fetchedMarkup.find(".content"));
	report.url = messageUrl;
	return report;
}

/**
 * parses the given message markup and returns an object.
 */ 
ReportToMail.parseReportMarkup = function(reportId, reportType, reportMarkup) {
	
	/**
	 * can parse unit or building rows.
	 */ 
	function parseInvolvedEntities(rowElement) { 
		var result = new Array();
		rowElement.children().slice(1).each(function() {
			var $this = $(this);
			result.push(Number($this.text()));
		});
		
		return result;
	}
	
	function parseCombatAndRecycleReport(report) {
		//Parse species
		report.firstSpecies = parseSpecies(reportMarkup.find("#ship_image_1").eq(0).attr("alt"));
		if (reportMarkup.find("#ship_image_1").length > 1) {
			report.secondSpecies = parseSpecies(reportMarkup.find("#ship_image_1").eq(1).attr("alt"));
		}
		
		//Parse units and buildings
		report.involvedEntities = new Array();
		var interestingRows = reportMarkup.find("tbody[class=colorGrey]>tr:has(td.fontCenter.fontSize12)");
		interestingRows.each(function() {
			var $this = $(this);
			report.involvedEntities.push(parseInvolvedEntities($this));
		});
		
		//Parse messages
		report.messages = new Array();
		reportMarkup.children("h3").each(function() {
			var $this = $(this);
			report.messages.push($this.text());
		});
	}
	
	function parseSpyReport(report) {
		//Parse species
		report.targetSpecies = parseSpecies(reportMarkup.find("#ship_image_1").eq(0).attr("alt"));
		
		//Parse units and buildings
		var interestingRows = reportMarkup.find("tbody>tr:has(td.fontCenter.fontSize12)");
		report.planetFleet = parseInvolvedEntities(interestingRows.eq(0));
	}
	
	function parseTradeReport(report) {
		var links = reportMarkup.find("div[class=fontSize12]").find("a");
		links.each(function() {
			$this = $(this);
			$this.attr("href", "http://" + window.location.host + $this.attr("href"));
		});
	
		report.content = reportMarkup.find("div[class=fontSize12]").html();
	}
	
	function parseSpecies(keyWord) {
		if (keyWord == $l("ship1_terrans"))
			return "terrans";
		if (keyWord == $l("ship1_titans"))
			return "titans";
		if (keyWord == $l("ship1_xen"))
			return "xen";
	}
	
	var report = new Object();
	report.id = reportId;
	report.type = reportType;
	
	//Parse general stuff
	var titleLinks = reportMarkup.children("h1").find("a");
	titleLinks.each(function() {
		$this = $(this);
		$this.attr("href", "http://" + window.location.host + $this.attr("href"));
	});
	report.linkedTitle = $.trim(reportMarkup.children("h1").html());
	report.title = $.trim(reportMarkup.children("h1").text());
	report.time = reportMarkup.children("h2").text();
	
	if (report.type == "combat" || report.type == "recycle")
		parseCombatAndRecycleReport(report);
	
	if (report.type == "espionage")
		parseSpyReport(report);
	
	if (report.type == "trade")
		parseTradeReport(report);
	
	return report;
}

/**
 * Collects checked messageRows.
 */ 
ReportToMail.collectCheckedReports = function() {
	var checkedLinks = $("a[class=checkbox interface_forms_checkbox_on]");
	return checkedLinks.parent().filter("td").parent();
}

ReportToMail.initialize();

})();